﻿using System;
using System.Diagnostics;

namespace Microsoft.Coding4Fun.TweetCraft.Twitter
{
    /// <summary>
    /// A Twitter update that was sent by a Twitter user.
    /// </summary>
    [DebuggerDisplay("Message = {Message}, User = {User}, DateSent = {DateSent}")]
    public class Tweet : IEquatable<Tweet>
    {
        /// <summary>
        /// Gets or sets the id of the tweet.
        /// </summary>
        public double Id { get; set; }

        /// <summary>
        /// Gets or sets the date and time when the tweet was sent.
        /// </summary>
        public DateTime DateSent { get; set; }

        /// <summary>
        /// Gets or sets the message of the tweet.
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// Gets or sets the <see cref="User"/> that sent the tweet.
        /// </summary>
        public User User { get; set; }

        /// <summary>
        /// Gets a string that contains the relative time that elapsed since the tweet.
        /// </summary>
        public string RelativeDateSent
        {
            get
            {
                return DateSent.ToRelativeTime(false);
            }
        }

        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator ==(Tweet left, Tweet right)
        {
            return Equals(left, right);
        }

        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator !=(Tweet left, Tweet right)
        {
            return !Equals(left, right);
        }

        /// <summary>
        /// Checks whether the current <see cref="Tweet"/> is equal to the other.
        /// </summary>
        /// <param name="other">The other.</param>
        /// <returns></returns>
        public bool Equals(Tweet other)
        {
            if (ReferenceEquals(null, other))
                return false;
            if (ReferenceEquals(this, other))
                return true;
            return other.Id == Id;
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
        /// </returns>
        /// <exception cref="T:System.NullReferenceException">
        /// The <paramref name="obj"/> parameter is null.
        /// </exception>
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
                return false;
            if (ReferenceEquals(this, obj))
                return true;
            if (obj.GetType() != typeof(Tweet))
                return false;
            return Equals((Tweet)obj);
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }
    }
}
